home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / crc.lqr / CRC.C next >
Text File  |  1985-06-03  |  7KB  |  139 lines

  1. /******************************************************************************
  2. *                                                                             *
  3. *               Cyclic Redundancy Check (CRC) functions                       *
  4. *                                                                             *
  5. *                                                                             *
  6. *                                                John F. Ratti                *
  7. *                                                06 January, 1984             *
  8. *                                                                             *
  9. *******************************************************************************
  10. *                                                                             *
  11. *                                                c/o Computer Power, Inc.     *
  12. *                                                P. O. Box 2388               *
  13. *                                                Jacksonville, FL  32231      *
  14. *                                                (904) 350-1400               *
  15. *                                                                             *
  16. ******************************************************************************/
  17.  
  18. /*
  19. *   crc_clear:
  20. *    This function clears the CRC to zero. It should be called prior to
  21. *    the start of the processing of a block for both received messages,
  22. *    and messages to be transmitted.
  23. *
  24. *    Calling sequence:
  25. *
  26. *    short crc;
  27. *    crc = crc_clear();
  28. */
  29. short crc_clear()
  30. {
  31.     return(0);
  32. }
  33. /*
  34. *   crc_update:
  35. *    this function must be called once for each character which is
  36. *    to be included in the CRC for both received messages,
  37. *    and messages to be transmitted.
  38. *
  39. *   Calling sequence:
  40. *
  41. *    crc = crc_update(crc,next_char);
  42. */
  43. short crc_update(crc,crc_char)
  44. short crc;
  45. char crc_char;
  46. {
  47.     long x;
  48.     short i;
  49.  
  50. /* "x" will contain the character to be processed in bits 0-7 and the CRC    */
  51. /* in bits 8-23. Bit 24 will be used to test for overflow, and then cleared  */
  52. /* to prevent the sign bit of "x" from being set to 1. Bits 25-31 are not    */
  53. /* used. ("x" is treated as though it is a 32 bit register).                 */
  54.     x = ((long)crc << 8) + crc_char;    /* Get the CRC and the character */
  55.  
  56. /* Repeat the following loop 8 times (for the 8 bits of the character).      */
  57.     for(i = 0;i < 8;i++)
  58.     {
  59.  
  60. /* Shift the high-order bit of the character into the low-order bit of the   */
  61. /* CRC, and shift the high-order bit of the CRC into bit 24.                 */
  62.         x = x << 1;                        /* Shift "x" left one bit */
  63.  
  64. /* Test to see if the old high-order bit of the CRC was a 1.                 */
  65.         if(x & 0x01000000)                     /* Test bit 24 of "x" */
  66.  
  67. /* If the old high-order bit of the CRC was a 1, exclusive-or it with a one  */
  68. /* to set it to 0, and exclusive-or the CRC with hex 1021 to produce the     */
  69. /* CCITT-recommended CRC generator of: X**16 + X**12 + X**5 + 1. To produce  */
  70. /* the CRC generator of: X**16 + X**15 + X**2 + 1, change the constant from  */
  71. /* 0x01102100 to 0x01800500. This will exclusive-or the CRC with hex 8005    */
  72. /* and produce the same CRC that IBM uses for their synchronous transmission */
  73. /* protocols.                                                                */
  74.             x = x ^ 0x01102100;     /* Exclusive-or "x" with a...*/
  75.                                               /* ...constant of hex 01102100 */
  76. /* And repeat 8 times.                                                       */
  77.     }                                               /* End of "for" loop */
  78.  
  79. /* Return the CRC as the 16 low-order bits of this function's value.         */
  80.     return(((x & 0x00ffff00) >> 8)); /* AND off the unneeded bits and... */
  81.                                   /* ...shift the result 8 bits to the right */
  82.  
  83. }
  84. /*
  85. *   crc_finish:
  86. *    This function must be called once after all the characters in a block
  87. *    have been processed for a message which is to be TRANSMITTED. It
  88. *    returns the calculated CRC bytes, which should be transmitted as the
  89. *    two characters following the block. The first of these 2 bytes
  90. *    must be taken from the high-order byte of the CRC, and the second
  91. *    must be taken from the low-order byte of the CRC. This routine is NOT
  92. *    called for a message which has been RECEIVED.
  93. *
  94. *   Calling sequence:
  95. *
  96. *    crc = crc_finish(crc);
  97. */
  98. short crc_finish(crc)
  99. short crc;
  100. {
  101. /* Call crc_update twice, passing it a character of hex 00 each time, to     */
  102. /* flush out the last 16 bits from the CRC calculation, and return the       */
  103. /* result as the value of this function.                                     */
  104.     return(crc_update(crc_update(crc,'\0'),'\0'));
  105.  
  106. }
  107.  
  108. /*
  109. * This is a sample of the use of the CRC functions, which calculates the
  110. * CRC for a 1-character message block, and then passes the resulting CRC back
  111. * into the CRC functions to see if the "received" 1-character message and CRC
  112. * are correct.
  113. */
  114. main()
  115. {
  116.     short crc;                                     /* The calculated CRC */
  117.     char crc_char;                            /* The 1-character message */
  118.     char x, y;            /* 2 places to hold the 2 "received" CRC bytes */
  119.  
  120.     crc_char = 'A';                    /* Define the 1-character message */
  121.     crc = crc_clear();      /* Reset the CRC to "transmit" a new message */
  122.     crc = crc_update(crc,crc_char);   /* Update the CRC for the first... */
  123.                                    /* ...(and only) character of the message */
  124.     crc = crc_finish(crc);        /* Finish the transmission calculation */
  125.     x = (char)((crc & 0xff00) >> 8);  /* Extract the high-order CRC byte */
  126.     y = (char)(crc & 0x00ff);          /* And extract the low-order byte */
  127.     printf("%04x\n",crc);                           /* Print the results */
  128.  
  129.     crc = crc_clear();                 /* Prepare to "receive" a message */
  130.     crc = crc_update(crc,crc_char);   /* Update the CRC for the first... */
  131.                                    /* ...(and only) character of the message */
  132.     crc = crc_update(crc,x);     /* Pass both bytes of the "received"... */
  133.     crc = crc_update(crc,y);           /* ...CRC through crc_update, too */
  134.     printf("%04x\n",crc);    /* If the result was 0, then the message... */
  135.                                             /* ...was received without error */
  136.  
  137. }
  138. /******************************** end of CRC.C *******************************/
  139.